﻿using System;
using System.Collections.Generic;
using System.Net;

using EmbeddedSensorCloud.HTTP;
using Newtonsoft.Json;

namespace EmbeddedSensorCloud.Plugin.MicroERP
{
    public class Controller
    {
        #region Fields

        private CommandFactory _CommandFactory;
        private Dictionary<Type, HttpStatusCode> _ExceptionStatusCodeSwitch;

        #endregion

        #region Constructor

        public Controller(DBType dbType, string dbConnectionString, IPdfService pdfService)
        {
            ICustomerDAO customerDao = DAOFactory.CreateCustomerDAO(dbType, dbConnectionString);
            IInvoiceDAO invoiceDao = DAOFactory.CreateInvoiceDAO(dbType, dbConnectionString);
            JsonSerializerSettings jsonSettings = new JsonSerializerSettings()
            {
                TypeNameHandling = TypeNameHandling.Objects,
                NullValueHandling = NullValueHandling.Ignore
            };
            this._CommandFactory = new CommandFactory(customerDao, invoiceDao, jsonSettings, pdfService);

            this._ExceptionStatusCodeSwitch = new Dictionary<Type, HttpStatusCode>()
            {
                { typeof(BadRequestException), HttpStatusCode.BadRequest },
                { typeof(JsonException), HttpStatusCode.BadRequest },
                { typeof(CustomerNotFoundException), HttpStatusCode.NotFound },
                { typeof(CompanyNotFoundException), HttpStatusCode.NotFound },
                { typeof(InvoiceNotFoundException), HttpStatusCode.NotFound },
                { typeof(CreateCustomerConflictException), HttpStatusCode.Conflict },
                { typeof(DeleteCustomerWithInvoicesException), HttpStatusCode.Forbidden }
            };
        }

        #endregion

        public Response CreateResponse(Request request)
        {
            ResponseEntity responseEntity = new ResponseEntity();
            Response httpResponse = new Response();

            try
            {
                ICommand command = this._CommandFactory.GetCommand(request);

                if (command == null)
                { throw new BadRequestException(); }

                responseEntity = command.Execute(request);
            }
            catch (Exception ex)
            {
                if (this._ExceptionStatusCodeSwitch.ContainsKey(ex.GetType()))
                {
                    responseEntity.StatusCode = this._ExceptionStatusCodeSwitch[ex.GetType()];
                }
                else
                {
                    responseEntity.StatusCode = HttpStatusCode.InternalServerError;
                }
            }
            httpResponse.Headers["Content-Type"] = responseEntity.ContentType;
            httpResponse.Body = responseEntity.Data;
            httpResponse.Status = responseEntity.StatusCode;
            
            return httpResponse;
        }
    }
}
